package com.example.hasordemo;

import java.sql.SQLException;

import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.alibaba.druid.pool.DruidDataSource;

import net.hasor.spring.boot.EnableHasor;
import net.hasor.spring.boot.EnableHasorWeb;

@Configuration
@EnableHasor()      // 在Spring 中启用 Hasor
@EnableHasorWeb()   // 将 hasor-web 配置到 Spring 环境中，Dataway 的 UI 是通过 hasor-web 提供服务。
public class ComponentConifg {
	
	@Bean
	public DataSource getDataSource() throws SQLException {
		DruidDataSource dataSource = new DruidDataSource();

		// 基本属性 url、user、password
		dataSource.setUrl( DBConfig.jdbcUrl );
		dataSource.setUsername( DBConfig.user );
		dataSource.setPassword( DBConfig.password );
		dataSource.setDriverClassName( DBConfig.driverClass );

		// 配置获取连接等待超时的时间(毫秒)
		dataSource.setMaxWait( 60000 );

		// 配置间隔多久才进行一次检测，检测需要关闭的空闲连接，单位是毫秒
		dataSource.setTimeBetweenEvictionRunsMillis( 60000 );

		// 配置一个连接在池中最小生存的时间，单位是毫秒
		// 连接保持空闲而不被驱逐的最长时间
		dataSource.setMinEvictableIdleTimeMillis( 300000 );

		// 配置timeBetweenLogStatsMillis>0之后，DruidDataSource会定期把监控数据输出到日志中。
		dataSource.setTimeBetweenLogStatsMillis( 300000 );

		// 用来检测连接是否有效的sql，要求是一个查询语句。如果validationQuery为null，testOnBorrow、testOnReturn、testWhileIdle都不会其作用。
		dataSource.setValidationQuery( "SELECT 'x'" );
		dataSource.setTestWhileIdle( true );// 建议配置为true，不影响性能，并且保证安全性。申请连接的时候检测，如果空闲时间大于timeBetweenEvictionRunsMillis，执行validationQuery检测连接是否有效。
		dataSource.setTestOnBorrow( false );// 申请连接时执行validationQuery检测连接是否有效，做了这个配置会降低性能。
		dataSource.setTestOnReturn( false );// 归还连接时执行validationQuery检测连接是否有效，做了这个配置会降低性能

		// 如果用Oracle，则把poolPreparedStatements配置为true，mysql可以配置为false。分库分表较多的数据库，建议配置为false
		// 打开PSCache，并且指定每个连接上PSCache的大小
		if ( DBConfig.jdbcUrl.toLowerCase().contains( "oracle" ) ) {
			dataSource.setValidationQuery( "SELECT 'x' FROM DUAL" );
			dataSource.setPoolPreparedStatements( true );
			dataSource.setMaxPoolPreparedStatementPerConnectionSize( 20 );
		}

		// 配置监控统计拦截的filters
		// 监控统计用的filter:stat 日志用的filter:log4j 防御sql注入的filter:wall
		// wall放在stat后边 --- 拦截检测的时间在StatFilter统计的SQL执行时间内
		dataSource.setFilters( "stat,wall" );

		// SQL合并配置
		// 保存DruidDataSource的监控记录
		// wallFilter:输出错误信息，不抛出异常信息
		// dataSource.setConnectionProperties(
		// "druid.stat.mergeSql=true;druid.stat.loggerName=bap.statLogger;druid.wall.logViolation=true;druid.wall.throwException=false;"
		// );

		return dataSource;
	}
}
